package com.chenl.interview.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chenl.interview.common.DeleteRequest;
import com.chenl.interview.common.ErrorCode;
import com.chenl.interview.common.ThrowUtils;
import com.chenl.interview.constant.CommonConstant;
import com.chenl.interview.constant.QuestionBankConstant;
import com.chenl.interview.exception.BusinessException;
import com.chenl.interview.model.dto.question.QuestionQueryRequest;
import com.chenl.interview.model.dto.questionBank.QuestionBankAddRequest;
import com.chenl.interview.model.dto.questionBank.QuestionBankQueryRequest;
import com.chenl.interview.model.entity.Question;
import com.chenl.interview.model.entity.QuestionBank;
import com.chenl.interview.model.entity.QuestionBankQuestion;
import com.chenl.interview.model.vo.QuestionBankVO;
import com.chenl.interview.model.vo.QuestionVO;
import com.chenl.interview.service.QuestionBankQuestionService;
import com.chenl.interview.service.QuestionBankService;
import com.chenl.interview.mapper.QuestionBankMapper;
import com.chenl.interview.service.QuestionService;
import com.chenl.interview.utils.SqlUtils;
import com.jd.platform.hotkey.client.callback.JdHotKeyStore;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

import static com.chenl.interview.constant.QuestionBankConstant.QUESTION_BANK_DETAIL;

/**
* @author chenl
* @description 针对表【question_bank(题库)】的数据库操作Service实现
* @createDate 2024-12-29 15:33:22
*/
@Service
public class QuestionBankServiceImpl extends ServiceImpl<QuestionBankMapper, QuestionBank>
    implements QuestionBankService{

    @Autowired
    @Lazy
    private QuestionService questionService;

    @Autowired
    @Lazy
    private QuestionBankQuestionService questionBankQuestionService;

    @Override
    public void validQuestionBank(QuestionBank questionBank, boolean add) {
        ThrowUtils.throwIf(questionBank == null, ErrorCode.PARAMS_ERROR);

        String title = questionBank.getTitle();
        String description = questionBank.getDescription();
        String picture = questionBank.getPicture();
        if (add) {
            ThrowUtils.throwIf(StringUtils.isAnyBlank(title,description,picture),ErrorCode.PARAMS_ERROR);
        }

        if (StringUtils.isNotBlank(title)) {
            ThrowUtils.throwIf(title.length() > 60,ErrorCode.OPERATION_ERROR,"标题过长");
        }
    }

    @Override
    public Long addQuestionBank(QuestionBankAddRequest questionBankAddRequest) {
        QuestionBank questionBank = BeanUtil.copyProperties(questionBankAddRequest, QuestionBank.class);
        //参数校验
        validQuestionBank(questionBank,true);

        boolean save = this.save(questionBank);
        if (!save) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }

        return questionBank.getId();
    }

    @Override
    public QuestionBankVO getQuestionBankVO(QuestionBankQueryRequest questionBankQueryRequest) {
        Long id = questionBankQueryRequest.getId();
        Boolean needQueryQuestionList = questionBankQueryRequest.getNeedQueryQuestionList();
        if (id == null || needQueryQuestionList == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        //检查是否hotKey
        String key = QUESTION_BANK_DETAIL + needQueryQuestionList + id;
        if (JdHotKeyStore.isHotKey(key)) {
            //是hotKey则从本地缓存中取值
            Object cache = JdHotKeyStore.get(key);
            if (cache != null) {
                return (QuestionBankVO) cache;
            }
        }

        //不是hotKey则从数据库中获取数据
        QuestionBank questionBank = this.getById(id);
        ThrowUtils.throwIf(questionBank == null,ErrorCode.NOT_FOUND_ERROR);

        QuestionBankVO questionBankVO = QuestionBankVO.objToVo(questionBank);
        //需要返回题库关联题目
        if (needQueryQuestionList){
            int current = questionBankQueryRequest.getCurrent();
            int pageSize = questionBankQueryRequest.getPageSize();

            QuestionQueryRequest questionQueryRequest = new QuestionQueryRequest();
            questionQueryRequest.setQuestionBankId(id);

            QueryWrapper<Question> queryWrapper = questionService.getQueryWrapper(questionQueryRequest);
            Page<Question> page = questionService.page(new Page<>(current, pageSize), queryWrapper);
            Page<QuestionVO> questionVOPage = questionService.getQuestionVOPage(page);

            questionBankVO.setQuestionPage(questionVOPage);
        }

        JdHotKeyStore.smartSet(key,questionBankVO);

        return questionBankVO;
    }

    @Override
    public Boolean deleteQuestionBank(DeleteRequest deleteRequest) {
        Long id = deleteRequest.getId();
        QuestionBank questionBank = this.getById(id);
        if (questionBank == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        //先删除对应的题库题目关联
        QueryWrapper<QuestionBankQuestion> queryWrapper = new QueryWrapper<QuestionBankQuestion>();
        queryWrapper.eq("questionBankId",id);
        boolean result = questionBankQuestionService.remove(queryWrapper);

        //删除题库
        result = result && this.removeById(id);

        if (!result) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        return result;
    }

    @Override
    public QueryWrapper<QuestionBank> getQueryWrapper(QuestionBankQueryRequest questionBankQueryRequest) {
        QueryWrapper<QuestionBank> queryWrapper = new QueryWrapper<>();
        if (questionBankQueryRequest == null) {
            return queryWrapper;
        }
        // todo 从对象中取值
        Long id = questionBankQueryRequest.getId();
        String searchText = questionBankQueryRequest.getSearchText();
        String title = questionBankQueryRequest.getTitle();
        String content = questionBankQueryRequest.getContent();
        String description = questionBankQueryRequest.getDescription();
        String sortField = questionBankQueryRequest.getSortField();
        String sortOrder = questionBankQueryRequest.getSortOrder();
        // todo 补充需要的查询条件
        // 从多字段中搜索
        if (StringUtils.isNotBlank(searchText)) {
            // 需要拼接查询条件
            queryWrapper.and(qw -> qw.like("title", searchText).or().like("content", searchText));
        }
        // 模糊查询
        queryWrapper.like(StringUtils.isNotBlank(title), "title", title);
        queryWrapper.like(StringUtils.isNotBlank(content), "content", content);
        queryWrapper.like(StringUtils.isNotBlank(description), "description", description);
        // JSON 数组查询

        // 精确查询
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        // 排序规则
        queryWrapper.orderBy(SqlUtils.validSortField(sortField),
                sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }

    @Override
    public Page<QuestionBankVO> getQuestionBankVOPage(Page<QuestionBank> questionBankPage) {
        List<QuestionBank> questionBankList = questionBankPage.getRecords();
        Page<QuestionBankVO> questionBankVOPage =
                new Page<>(questionBankPage.getCurrent(), questionBankPage.getSize(), questionBankPage.getTotal());
        if (CollUtil.isEmpty(questionBankList)) {
            return questionBankVOPage;
        }
        // 对象列表 => 封装对象列表
        List<QuestionBankVO> questionBankVOList = questionBankList.stream().map(questionBank -> {
            return QuestionBankVO.objToVo(questionBank);
        }).collect(Collectors.toList());

        questionBankVOPage.setRecords(questionBankVOList);

        return questionBankVOPage;
    }
}




